#ifndef DNDDATA_H_
#define DNDDATA_H_

#include <QTextStream>

class Race;
class CacheEntry;
class Trait;
class Power;

class DndData
{
public:
    enum Tier {
        HEROIC,
        PARAGON,
        EPIC_DESTINY
    };

    static const int NUM_TIERS = 3;
    static const char *TIER_NAMES[];

    enum Ability {
        STRENGTH,
        CONSTITUTION,
        DEXTERITY,
        INTELLIGENCE,
        WISDOM,
        CHARISMA
    };

    static const int NUM_ABILITIES = 6;
    static const char *ABILITY_NAMES[];

    static const int STANDARD_ARRAY[];
    static const int CUSTOMIZED_COSTS[];
    static const int CUSTOMIZE_SCORES_ARRAY[];
    static const int CUSTOMIZED_POINTS;

    enum DefenceType {
        ARMOUR_CLASS,
        FORTITUDE_DEFENCE,
        WILL_DEFENCE,
        REFLEXES_DEFENCE
    };

    enum RaceName {
        DRAGONBORN,
        DWARF,
        ELADRIN,
        ELF,
        HALF_ELF,
        HALFLING,
        HUMAN,
        TIEFLING
    };

    static const int NUM_RACES = 8;
    static const char *RACE_NAMES[];

    enum ClassName {
        CLERIC,
        FIGHTER,
        PALADIN,
        RANGER,
        ROGUE,
        WARLOCK,
        WARLORD,
        WIZARD
    };

    static const int NUM_CLASSES = 8;
    static const char *CLASS_NAMES[];

    enum BodySize {
        TINY_SIZE,
        SMALL_SIZE,
        MEDIUM_SIZE,
        LARGE_SIZE,
        HUGE_SIZE,
        GARGANTUAN_SIZE
    };

    static const int NUM_SIZES = 6;
    static const char *SIZE_NAMES[];

    enum VisionType {
        NORMAL_VISION,
        LOW_LIGHT_VISION,
        DARK_VISION
    };

    static const int NUM_VISION_TYPES = 3;
    static const char *VISION_TYPES[];

    enum Language {
        ABYSSAL_LANGUAGE,
        COMMON_LANGUAGE,
        DEEP_SPEECH_LANGUAGE,
        DRACONIC_LANGUAGE,
        DWARVEN_LANGUAGE,
        ELVEN_LANGUAGE,
        GIANT_LANGUAGE,
        GOBLIN_LANGUAGE,
        PRIMORDIAL_LANGUAGE,
        SUPERNAL_LANGUAGE,
        CHOICE_LANGUAGE
    };

    static const int NUM_LANGUAGES = 11;
    static const char *LANGUAGE_NAMES[];

    enum SkillTypes {
        ACROBATICS,
        ARCANA,
        ATHLETICS,
        BLUFF,
        DIPLOMACY,
        DUNGEONEERING,
        ENDURANCE,
        HEAL,
        HISTORY,
        INSIGHT,
        INTIMIDATE,
        NATURE,
        PERCEPTION,
        RELIGION,
        STEALTH,
        STREETWISE,
        THIEVERY
    };

    static const int NUM_SKILL_TYPES = 17;
    static const char *SKILL_TYPES[];

    enum PartyRole
    {
        LEADER_ROLE,
        CONTROLLER_ROLE,
        DEFENDER_ROLE,
        STRIKER_ROLE
    };

    static const int NUM_PARTY_ROLES = 4;
    static const char *ROLE_NAMES[];

    enum Gender
    {
        MALE_GENDER,
        FEMALE_GENDER
    };

    static const int NUM_GENDERS = 2;
    static const char *GENDER_NAMES[];

    enum Alignments
    {
        GOOD_ALIGNMENT,
        LAWFUL_GOOD_ALIGNMENT,
        UNALIGNED_ALIGNMENT,
        EVIL_ALIGNMENT,
        CHAOTIC_EVIL_ALIGNMENT
    };

    static const int NUM_ALIGNMENTS = 5;
    static const char *ALIGNMENT_NAMES[];

    enum Deities
    {
        AVANDRA_DEITY,
        BAHAMUT_DEITY,
        CORELLON_DEITY,
        ERATHIS_DEITY,
        IOUN_DEITY,
        KORD_DEITY,
        MELORA_DEITY,
        MORADIN_DEITY,
        PELOR_DEITY,
        RAVEN_QUEEN_DEITY,
        SEHANINE_DEITY
    };

    static const int NUM_DEITIES = 11;
    static const char *DEITY_NAMES[];

    enum EvilDeities
    {
        ASMODEUS_EVIL_DEITY,
        BANE_EVIL_DEITY,
        GRUUMSH_EVIL_DEITY,
        LOLTH_EVIL_DEITY,
        TIAMAT_EVIL_DEITY,
        TOROG_EVIL_DEITY,
        VECNA_EVIL_DEITY,
        ZEHIR_EVIL_DEITY
    };

    static const int NUM_EVIL_DEITIES = 8;
    static const char *EVIL_DEITY_NAMES[];

    enum ArmourWeights
    {
        LIGHT_ARMOUR,
        HEAVY_ARMOUR
    };

    static const int NUM_ARMOUR_WEIGHTS = 2;
    static const char *ARMOUR_WEIGHT_NAMES[];

    // The abilities in order, best suited for each class
    static const int APTITUDE_ABILITIES[][NUM_ABILITIES];

    // Calculate the ability modifier for the given ability, see table
    // on page 17 of PHB.
    static int abilityModifier(int ability)
    {
        return (ability / 2) - 5;
    }

    DndData();
    virtual ~DndData();
};

QTextStream & operator>>(QTextStream &s, DndData::Ability &data);
QTextStream & operator>>(QTextStream &s, DndData::DefenceType &data);
QTextStream & operator>>(QTextStream &s, DndData::ClassName &data);
QTextStream & operator>>(QTextStream &s, DndData::RaceName &data);
QTextStream & operator>>(QTextStream &s, DndData::BodySize &data);
QTextStream & operator>>(QTextStream &s, DndData::VisionType &data);
QTextStream & operator>>(QTextStream &s, DndData::SkillTypes &data);
QTextStream & operator>>(QTextStream &s, DndData::PartyRole &data);
QTextStream & operator>>(QTextStream &s, DndData::Language &data);
QTextStream & operator>>(QTextStream &s, DndData::Tier &data);

#endif /*DNDDATA_H_*/
